home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / xcoral / xcoral.lha / xcoral-1.72 / handle_key.c < prev    next >
C/C++ Source or Header  |  1993-02-11  |  12KB  |  558 lines

  1. /*
  2. ** Copyright 1989, 1992 by Lionel Fournigault
  3. **
  4. ** Permission to use, copy, and distribute for non-commercial purposes,
  5. ** is hereby granted without fee, providing that the above copyright
  6. ** notice appear in all copies and that both the copyright notice and this
  7. ** permission notice appear in supporting documentation.
  8. ** The software may be modified for your own purposes, but modified versions
  9. ** may not be distributed.
  10. ** This software is provided "as is" without any expressed or implied warranty.
  11. **
  12. **
  13. */
  14.  
  15. #include <stdio.h>
  16. #include <X11/Xlib.h>
  17. #include <X11/cursorfont.h>
  18. #include <X11/Xutil.h>
  19. #include <X11/keysym.h>
  20. #include <ctype.h>
  21. #include <strings.h>
  22.  
  23. #include "xcoral.h"
  24. #include "flist.h"
  25.  
  26. extern EdWin *edwin;
  27. extern Display *dpy;
  28.  
  29. extern Trans st_initial[], st_control_x[], st_escape[];
  30. static int    f_ascii (), f_nothing (), f_controle (), f_escape (), f_ctr (),
  31.     f_special (), f_ctrx ();
  32.  
  33. #if ((__osf__) && (__alpha))
  34. Trans st_initial [8] = {
  35.     { KEY, f_ascii, (long) st_initial },
  36.     { CONTROL, f_nothing, (long) st_initial },
  37.     { CONTROL_AND_KEY, f_ctr, (long) st_initial },
  38.     { CONTROL_AND_X, f_nothing, (long) st_control_x },
  39.     { ESCAPE, f_escape, (long) st_escape },
  40.     { ARROW, f_ascii, (long) st_initial },
  41.     { SPECIAL, f_special, (long) st_initial },
  42.     { 0, 0, 0 }
  43. };
  44. Trans st_control_x [8] = {
  45.     { KEY, f_ctrx, (long) st_initial },
  46.     { CONTROL, f_nothing, (long) st_control_x },
  47.     { CONTROL_AND_KEY, f_ctrx, (long) st_initial },
  48.     { CONTROL_AND_X, f_ctrx, (long) st_initial },
  49.     { ESCAPE, f_escape, (long) st_escape },
  50.     { ARROW, f_ascii, (long) st_initial },
  51.     { SPECIAL, f_special, (long) st_control_x },
  52.     { 0, 0, 0 }
  53. };
  54.  
  55. Trans st_escape [8] = {
  56.     { KEY, f_escape, (long) st_initial },
  57.     { CONTROL, f_nothing, (long) st_initial },
  58.     { ESCAPE, f_escape, (long) st_initial },
  59.     { ARROW, f_ascii, (long) st_escape },
  60.     { SPECIAL, f_special, (long) st_escape },
  61.     { 0, 0, 0 },
  62.     { 0, 0, 0 },
  63.     { 0, 0, 0 }
  64. };
  65. #else
  66. Trans st_initial [8] = {
  67.     { KEY, f_ascii, (int) st_initial },
  68.     { CONTROL, f_nothing, (int) st_initial },
  69.     { CONTROL_AND_KEY, f_ctr, (int) st_initial },
  70.     { CONTROL_AND_X, f_nothing, (int) st_control_x },
  71.     { ESCAPE, f_escape, (int) st_escape },
  72.     { ARROW, f_ascii, (int) st_initial },
  73.     { SPECIAL, f_special, (int) st_initial },
  74.     { 0, 0, 0 }
  75. };
  76.  
  77. Trans st_control_x [8] = {
  78.     { KEY, f_ctrx, (int) st_initial },
  79.     { CONTROL, f_nothing, (int) st_control_x },
  80.     { CONTROL_AND_KEY, f_ctrx, (int) st_initial },
  81.     { CONTROL_AND_X, f_ctrx, (int) st_initial },
  82.     { ESCAPE, f_escape, (int) st_escape },
  83.     { ARROW, f_ascii, (int) st_initial },
  84.     { SPECIAL, f_special, (int) st_control_x },
  85.     { 0, 0, 0 }
  86. };
  87.  
  88. Trans st_escape [8] = {
  89.     { KEY, f_escape, (int) st_initial },
  90.     { CONTROL, f_nothing, (int) st_initial },
  91.     { ESCAPE, f_escape, (int) st_initial },
  92.     { ARROW, f_ascii, (int) st_escape },
  93.     { SPECIAL, f_special, (int) st_escape },
  94.     { 0, 0, 0 },
  95.     { 0, 0, 0 },
  96.     { 0, 0, 0 }
  97. };
  98. #endif
  99. static int     num;        /* Pour les repetitions        */
  100. static char     ns [32];        
  101. static int     last_stat;    /* Pour les sequences escapes    */
  102. static deletewindow = False;
  103.  
  104. static KeySym    ksym;
  105. XComposeStatus    compose;
  106. static int     n_bytes;
  107.  
  108. static void GetInfosKey (), GetInfosAsciiKey (), GetDigit ();
  109.  
  110. /*
  111. **    Function name : automate
  112. **
  113. **    Description : Un petit automate, pour s'amuser...
  114. **        Il a trois etats possibles :
  115. **        - initial ( etat par default )
  116. **        - controle_x ( sequence Ctr X ... )
  117. **        - escape ( Avec en plus le "repeat" )
  118. **    Input : 
  119. **    Ouput :
  120. */
  121. ST *automate ( event, current_st )
  122.     XKeyEvent *event;
  123.     ST *current_st;
  124. {
  125.     char buf [32];
  126.     register int i;
  127.     InfosKey infos;
  128.        
  129.        bzero (buf, 32);
  130.     n_bytes = XLookupString ( event, buf, 32, &ksym, &compose );
  131. #ifdef DEBUG
  132.     printf ( "n_bytes = %d %X\n", n_bytes, ksym );
  133. #endif
  134.     (void) GetInfosKey ( ksym, buf [0], &infos );
  135.  
  136.     deletewindow = False;
  137.  
  138.     for ( i=0; current_st -> trans [i].type != 0; i++ ){
  139.         if ( current_st -> trans [i].type == infos.type ) {
  140.             if ( current_st -> trans [i].fnt == 0 || current_st -> trans [i].dest_stat == 0 ) {
  141.                 (void) fprintf ( stderr, "Error trans = %d\n", i );
  142.                          if ( deletewindow == False )
  143.                     return ( (ST *) current_st );
  144.                          else
  145.                              return ( (ST *) - 1 );    
  146.             }
  147.             current_st -> trans [i].fnt ( &infos );
  148.                   if ( deletewindow == False )
  149.                 return ( ( ST * ) current_st -> trans [i].dest_stat );
  150.                   else
  151.                       return ( (ST *) - 1 );    
  152.         }
  153.     }
  154.     (void) fprintf ( stderr, "Automate error\n" );
  155.     return ( (ST *) st_initial );
  156. }
  157.  
  158.  
  159. /*
  160. **    Function name : GetInfosKey
  161. **
  162. **    Description : GetInfosKey remplie la structure InfosKey
  163. **        en fonction du symbol relatif a l'evenement
  164. **        touche enfoncee.
  165. **        On cherche a savoir dans un premier temps si la
  166. **        touche est de type controle, escape, ou fleche.
  167. **    Input : Le symbole, le caractere, les infos.
  168. **    Ouput :
  169. */
  170. static void GetInfosKey ( ksym, c, infos )
  171.     KeySym        ksym;
  172.     char         c;
  173.     InfosKey     *infos;
  174. {
  175.     switch ( ksym ) {
  176.         case XK_Control_L :
  177.         case XK_Control_R :
  178.             infos -> type = CONTROL;
  179.             infos -> ch = 0;
  180.             ClearMessageWindow ( edwin -> mwin );
  181.             break;
  182.         case XK_Escape     :
  183.         case XK_Meta_L    :
  184.         case XK_Meta_R    :
  185.             infos -> type = ESCAPE;
  186.             infos -> ch = c;
  187.             ClearMessageWindow ( edwin -> mwin );
  188.             break;
  189.         case XK_Right :
  190.                 infos -> ch = 'f';
  191.             infos -> type = ARROW;
  192.             break;
  193.         case XK_Left     :
  194.             infos -> ch = 'b';
  195.             infos -> type = ARROW;
  196.             break;
  197.         case XK_Up    :
  198.                 infos -> ch = 'p';
  199.             infos -> type = ARROW;
  200.                 break;
  201.         case XK_Down    :
  202.             infos -> ch = 'n';
  203.             infos -> type = ARROW;
  204.             break;
  205.         default:
  206.             (void) GetInfosAsciiKey ( c, infos );
  207.             break;
  208.     }
  209. }
  210.  
  211. /*
  212. **    Function name : GetInfosAsciiKey
  213. **
  214. **    Description : GetInfosAsciiKey remplie la structure InfosKey
  215. **        dans les cas suivants:
  216. **        - Sequence Controle X
  217. **        - Sequence Controle + Key
  218. **        - Return, tab, delete, backspace space
  219. **        - Caractere imprimable.
  220. **    Input : Le symbole, le caractere et les infos.
  221. **    Ouput :
  222. */
  223. static void GetInfosAsciiKey ( c, infos )
  224.     char         c;
  225.     InfosKey    *infos;
  226. {
  227.  
  228.     if ( c >= 0 && c <= CtrZ && n_bytes != 0 ) {
  229.         switch ( c ) {
  230.             case CtrX    :
  231.                 infos -> type = CONTROL_AND_X;
  232.                 break;
  233.             case RETURN     :
  234.             case LINEFEED    :
  235.             case TAB     :
  236.             case BACKSPACE    :
  237.                     infos -> type = KEY;
  238.                 break;
  239.             default:
  240.                 infos -> type = CONTROL_AND_KEY;
  241.                 break;
  242.         }
  243.         ClearMessageWindow ( edwin -> mwin );
  244.         infos -> ch = c;
  245.         return;
  246.     }
  247.     else if ( last_stat == REPEAT ) {
  248.         if ( isdigit ( c ))
  249.             infos -> type = ESCAPE;
  250.         else {
  251.             last_stat = 0;
  252.             infos -> type = KEY;
  253.             ClearMessageWindow ( edwin -> mwin );
  254.         }
  255.         infos -> ch = c;
  256.     }
  257.     else if ( n_bytes == 1 ) {
  258.             infos -> ch = c;
  259.         infos -> type = KEY;
  260.     }
  261.     else {
  262.         infos -> type = SPECIAL; infos -> ch = 0;
  263.     }
  264. }
  265.  
  266.  
  267. /*
  268. **    Function name : f_ascii
  269. **
  270. **    Description : Traitement des caracteres ascii
  271. **    Input : Le infos.
  272. **    Ouput :
  273. */
  274. static f_ascii ( infos )
  275.     InfosKey *infos;    
  276. {
  277.     if ( infos -> type == ARROW ) {
  278.            TextCursorOff ( edwin -> text );
  279.            switch ( infos -> ch ) {
  280.            case 'n':
  281.          DownCursor ( edwin -> text );
  282.          break;
  283.            case 'p':
  284.          UpCursor ( edwin -> text );
  285.          break;
  286.            case 'f':
  287.          (void) ForwardChar ( edwin -> text );
  288.          break;
  289.            case 'b':
  290.          BackwardChar ( edwin -> text );
  291.          break;
  292.            }
  293.            TextCursorOn ( edwin -> text );
  294.            return;
  295.     }
  296.     
  297.     switch ( infos -> ch ) {
  298.         case TAB :
  299.                f_tab ( edwin -> text );
  300.                break;
  301.         case DELETE:
  302.         case BACKSPACE:
  303.                f_delete ( edwin -> text );
  304.                break;
  305.         case LINEFEED:
  306.         case RETURN:
  307.             f_return ( edwin -> text );
  308.                break;
  309.                 default :
  310.                if ( isprint ( infos -> ch ) )
  311.                       f_impc ( edwin -> text, infos -> ch );
  312.     }
  313. }
  314.  
  315.  
  316. /*
  317. **    Function name : f_ctrx
  318. **
  319. **    Description : Traitement des sequences ^X ^key
  320. **    Input : Les infos. 
  321. **    Ouput :
  322. */
  323. static int f_ctrx ( infos )
  324.     InfosKey *infos;
  325. {
  326.     register int n;
  327.        register char *str;
  328.     char c = '\007';
  329.  
  330.     switch ( infos -> ch ) {
  331.         case CtrC :
  332.                   if ( DeleteWindow ( edwin -> text ) == 0 )
  333.                 deletewindow = True;    
  334.             break;
  335.         case CtrS :
  336.             KbdSaveFile ( edwin -> text );
  337.             break;
  338.         case CtrF :
  339.             KbdReadFile ( edwin -> text );
  340.             break;
  341.         case CtrW :
  342.             KbdWriteFile ( edwin -> text );
  343.             break;
  344.         case CtrX:
  345.             ExchangePointMark ( edwin -> text );
  346.             break;
  347.         case 'b':
  348.             DisplayOpenFiles ( edwin -> text );
  349.             break;
  350.         case 'k':
  351.             TextCursorOff ( edwin -> text );
  352.             KillCurrentBuffer ( edwin -> text, F_KEY );
  353.             TextCursorOn ( edwin -> text );
  354.             break;
  355.         case 'l':
  356.             TextCursorOff ( edwin -> text );
  357.                   str = (char *) GetString ( edwin -> text, "Goto Line : ", (char *) 0 );
  358.             if ( (str == 0) || (strncmp (str, &c, 1 ) == 0) || ((n = atoi ( str )) == 0) )
  359.                 DisplayMessage ( edwin -> text -> mwin, "Abort" );
  360.                   else {
  361.                 GotoLineNumber ( edwin -> text, n );
  362.                 CurrentLineToMiddle ( edwin -> text ); 
  363.             }
  364.             TextCursorOn ( edwin -> text );
  365.             num = 0;
  366.             break;
  367.         case 'i':
  368.             KbdInsertFile ( edwin -> text );
  369.             break;
  370.  
  371.         case '2':
  372.             NewWindow ( edwin -> text );
  373.             break;
  374.         default :
  375.             break;
  376.     }
  377. }
  378.  
  379.  
  380. /*
  381. **    Function name : f_ctr
  382. **
  383. **    Description : Traitement des sequences ^key
  384. **    Input : Les infos.
  385. **    Ouput :
  386. */
  387. static int f_ctr ( infos )
  388.     InfosKey *infos;
  389. {
  390.     TextCursorOff ( edwin -> text );    
  391.  
  392.     switch ( infos -> ch ) {
  393.         case CtrA:
  394.             MoveToBline ( edwin ->text );
  395.             break;
  396.         case CtrB:
  397.             BackwardChar ( edwin -> text );
  398.             break;
  399.         case CtrD :
  400.             Control_D ( edwin -> text );
  401.             break;
  402.         case CtrE:
  403.             MoveToEline ( edwin -> text );
  404.             break;
  405.         case CtrF:
  406.             (void) ForwardChar ( edwin -> text );
  407.             break;
  408.         case CtrG:
  409.             DisplayMessage ( edwin -> mwin, "Abort" );
  410.             num = 0;
  411.             if ( last_stat == REPEAT )
  412.                 last_stat = 0;
  413.             ResetSearchString ();
  414.             break;
  415.         case CtrK:
  416.             if ( num == 0 ) num++;
  417.             Control_K ( edwin -> text, num );
  418.             num = 0;
  419.             break;
  420.         case CtrL:
  421.             ClipOn ( edwin -> text, 0 );
  422.             RefreshPage ( edwin -> text );
  423.             ClipOff ( edwin -> text );
  424.             break;
  425.         case CtrN:
  426.             DownCursor ( edwin -> text );
  427.             break;
  428.         case CtrO:
  429.             f_return ( edwin -> text );
  430.             TextCursorOff ( edwin -> text );            
  431.             BackwardChar ( edwin -> text );
  432.             break;
  433.         case CtrP:
  434.             UpCursor (  edwin -> text );
  435.             break;
  436.         case CtrR:
  437.             BackwardSearch ( edwin -> text );
  438.             break;
  439.         case CtrS:
  440.             ForwardSearch ( edwin -> text );
  441.             break;
  442.         case CtrV:
  443.             NextPage ( edwin -> text );
  444.             break;
  445.         case CtrW:
  446.             KillRegion ( edwin -> text );
  447.             break;
  448.                     case CtrY:
  449.             if ( num == 0 )
  450.                    Control_Y ( edwin -> text, 0 );
  451.             else 
  452.                    Control_Y ( edwin -> text, num-1 );
  453.             num = 0;
  454.             break;
  455.         case Ctr_sp:
  456.             SetMark ( edwin -> text );
  457.             break;
  458.         default :
  459.             ;
  460.     }
  461.     TextCursorOn ( edwin -> text );
  462. }
  463.  
  464.  
  465. /*
  466. **    Function name : f_escape
  467. **
  468. **    Description : Traitement des sequences escape.
  469. **    Input : 
  470. **    Ouput :
  471. */
  472. static int f_escape ( infos )
  473.     InfosKey    *infos;
  474. {
  475.     TextCursorOff ( edwin -> text );    
  476.  
  477.     switch ( infos -> ch ) {
  478.         case '<':
  479.             FirstPage ( edwin -> text );
  480.             break;
  481.         case '>' :
  482.             GotoEnd ( edwin -> text );
  483.             CurrentLineToMiddle ( edwin -> text );
  484.             break;
  485.         case 'v' :
  486.             PreviousPage ( edwin -> text );
  487.             break;
  488.         case 'r':
  489.             GlobalReplace ( edwin -> text );
  490.             break;
  491.         case 'q':
  492.             QueryReplace ( edwin -> text );
  493.             break;
  494.         case 'w':
  495.             CopyRegion ( edwin -> text );
  496.             break;
  497.         default  :
  498.             GetDigit ( infos );
  499.             break;
  500.     }
  501.  
  502.     TextCursorOn ( edwin -> text );
  503. }
  504.  
  505. /*
  506. **    Function name : GetDigit
  507. **
  508. **    Description : Traitement la sequence escape num
  509. **    Input : Les infos.
  510. **    Ouput :
  511. */
  512. static void GetDigit ( infos )
  513.     InfosKey *infos;
  514. {
  515.     char str [32];
  516.     char tmp[2];
  517.  
  518.     if ( isdigit ( infos -> ch )) {
  519.         tmp [0] = infos -> ch; tmp [1] = 0;
  520.         (void) strcat  ( ns, tmp );
  521.  
  522.         if ( atoi(ns) > MAXREPEAT ) {
  523.             DisplayMessage ( edwin -> mwin, "Too much...bye" );
  524.             last_stat = 0;
  525.             ns [0] = num = 0;
  526.             return;
  527.         }
  528.  
  529.         if ( last_stat == REPEAT )
  530.             (void) sprintf ( str,"Repeat : %d%c", num, infos -> ch );
  531.         else {
  532.             (void) sprintf ( str,"Repeat : %c", infos -> ch );
  533.             last_stat = REPEAT;
  534.         }
  535.         DisplayMessage ( edwin -> mwin,  str );
  536.         num = atoi (ns);    
  537.     }
  538.     else {
  539.         last_stat = 0;
  540.         ns [0] = num = 0;
  541.         if ( isprint ( infos -> ch ) && infos -> ch != ESCAPE ) {
  542.             f_impc ( edwin -> text, infos -> ch );
  543.             ClearMessageWindow ( edwin -> mwin);
  544.         }
  545.     }
  546. }
  547.  
  548. static int f_nothing (){}
  549. static int f_special ( infos, edwin )
  550.     InfosKey *infos;
  551.     EdWin    *edwin;
  552. {
  553. #ifdef lint
  554.     (void) fprintf ( stderr, "dpy = %d infos = %d edwin = %d\n",
  555.         (int) dpy, (int) infos, (int) edwin );
  556. #endif
  557. }
  558.